#ifndef LoopReader_H
#define	LoopReader_H

class LoopReader
{
public:
	LoopReader():
		m_width(),
		m_height(),
		m_fps(),
		m_codec(),
		m_channels(),
		m_sampleRate(),
		m_acodec()
	{

	}

	~LoopReader()
	{
		close();
	}

	int open(const char* url)
	{
		m_reader.reset(new FfmpegMediaReader());
		int rc = m_reader->open(url);
		if (rc == 0)
		{
			m_width = m_reader->m_width;
			m_height = m_reader->m_height;
			m_fps = m_reader->m_fps;
			m_codec = m_reader->m_codec;
			m_prop = m_reader->m_prop;

			m_channels = m_reader->m_channels;
			m_sampleRate = m_reader->m_sampleRate;
			m_acodec = m_reader->m_acodec;
			m_config = m_reader->m_config;

			m_url = url;

			memset(m_ptsOffset, 0, sizeof(m_ptsOffset));
			memset(m_ptsLast, 0, sizeof(m_ptsLast));
			
			m_duration = m_reader->getDuration();
		}
		return rc;
	}

	void close()
	{
		if (m_reader)
		{
			m_reader->close();
			m_reader.reset();
		}
	}

	int read(AVPacket& pkt)
	{
		int rc = doRead(pkt);
		if (rc != 0)
		{
			memcpy(m_ptsOffset, m_ptsLast, sizeof(m_ptsOffset));

			m_reader.reset(new FfmpegMediaReader());
			m_reader->open(m_url.c_str());
			rc = doRead(pkt);
		}
		return rc;
	}

	int doRead(AVPacket& pkt)
	{
		int rc = m_reader->read(pkt);
		if (rc == 0)
		{
			if (pkt.dts == AV_NOPTS_VALUE)
			{
				pkt.dts = 1;
				pkt.pts = 1;
			}

			pkt.dts += m_ptsOffset[pkt.stream_index];
			pkt.pts = pkt.dts;

			m_ptsLast[pkt.stream_index] = pkt.dts;
		}
		return rc;
	}

	static bool isVideo(AVPacket& pkt)
	{
		return FfmpegMediaReader::isVideo(pkt);
	}

	bool isLive()
	{
		return m_duration <= 0;
	}

	int	m_width;
	int m_height;
	int m_fps;
	AVCodecID	m_codec;
	std::string	m_prop;

	int m_channels;
	int m_sampleRate;
	AVCodecID	m_acodec;
	std::string	m_config;

	std::string	m_url;

	int64_t	m_ptsOffset[2];
	int64_t	m_ptsLast[2];

	int64_t	m_duration;

protected:
	std::shared_ptr< FfmpegMediaReader >	m_reader;

};

#endif //LoopReader_H